#include "ZoogVM.h"

#include "standard_malloc_factory.h"
#include "malloc_factory_operator_new.h"

void test_memory_fail()
{
	char *p;
	asm(
		"mov %%esp,%0"
		: "=r"(p)
		);
	for (; ; p--)
	{
		char c = *p;
		(void) c;
	}
}

void dummy()
{
}

int main(int argc, char **argv)
{
	MallocFactory *mf = standard_malloc_factory_init();
	malloc_factory_operator_new_init(mf);

	uint8_t test_code[] = {
//		0xb8, 0x09, 0x20, 0x00, 0x00,	// mov 2009 eax
//		0xa3, 0xfc, 0x0f, 0x00, 0x00,	// mov eax 0xffc
//		0xa3, 0x22, 0x10, 0x00, 0x00,	// mov eax 0x1000
//		0xf4,
		0xb8, 0x10, 0x00, 0x00, 0x00,	// mov $0x10, %eax
		0x8e, 0xe8,						// mov %eax,%gs
		0x65, 0x8b, 0x15, 0x00, 0x00, 0x00, 0x00,	// mov %gs:(0),%edx
		0xba, 0xee, 0x09, 0x20, 0xee,				//mov    $0xee2009ee,%edx
		0x65, 0x89, 0x15, 0x00, 0x00, 0x00, 0x00,	// mov    %edx,%gs:0x0
		0xf4,							// hlt
		0xb8, 0x18, 0x00, 0x00, 0x00,	// mov $0x18, %eax
		0x8e, 0xe8,						// mov %eax,%gs
		0x65, 0x8b, 0x15, 0x00, 0x00, 0x00, 0x00,	// mov %gs:(0),%edx
		0xba, 0xee, 0x09, 0x20, 0xee,				//mov    $0xee2009ee,%edx
		0x65, 0x89, 0x15, 0x00, 0x00, 0x00, 0x00,	// mov    %edx,%gs:0x0
		0xf4,							// hlt
		0xb8, 0x20, 0x00, 0x00, 0x00,	// mov $0x20, %eax
		0x8e, 0xe8,						// mov %eax,%gs
		0x65, 0x8b, 0x15, 0x00, 0x00, 0x00, 0x00,	// mov %gs:(0),%edx
		0xba, 0xee, 0x09, 0x20, 0xee,				//mov    $0xee2009ee,%edx
		0x65, 0x89, 0x15, 0x00, 0x00, 0x00, 0x00,	// mov    %edx,%gs:0x0
		0xf4,							// hlt

		0x90, 0x90, 0x90,			// nop sled
//		0x0f, 0x01, 0xc1,	// vmcall
		0xf4,				// hlt
		0x81, 0xc3, 0x03, 0x30, 0x03, 0x00,	// add $3003,%ebx
		0xeb, 0xf7			// jump back 9
		};
	(void) test_code;

	ZoogVM *zvm = new ZoogVM(mf, ZOOG_TUNID);
	//uint32_t guest_entry_point = zvm->map_image(test_code, sizeof(test_code), "dummy_guest_image");
	uint32_t tmf_len = ((uint32_t) &dummy) - ((uint32_t) &test_memory_fail);
	uint32_t guest_entry_point = zvm->map_image((uint8_t*) &test_memory_fail, tmf_len, "test_memory_fail");
	zvm->set_guest_entry_point(guest_entry_point);
	zvm->dbg_dump_memory_map();
	zvm->start();
}
